home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fritz: All Fritz
/
All Fritz.zip
/
All Fritz
/
FILES
/
DEMO_VGA
/
JULIA.LZH
/
JUL.ASM
next >
Wrap
Assembly Source File
|
1980-01-01
|
6KB
|
193 lines
PAGE 255,132
; Q
; Juline calculates a horozontal row of points for a quadratic
; Julia set. The parameters are scaled to be close to the maximum
; magnitude for integers and integer arithmetic is used for speed.
; The unscaled Julia set is associated with the transformation
;
; z --> z^2 - L in the region abs(Re(z)) < 2 and abs(Im(z))<1
;
; To scale to maximum size we use
;
; x = Re(z) * 2^14 y = Im(z) * 2^15
; a = Re(L) * 2^14 b = Im(L) * 2^12
;
; The transformation can then be written
;
; x --> [4x^2/2^16 - (2^15 - 1)] - [ y^2/2^16 + (a - 2^15 + 1)]
; y --> (8(xy - b*2^16))/2^16
;
; The intermediate multiplication results are two words long. Each
; 2^16 indicates a simple full word shift. The multiplications by
; 4 and 8 indicate shifts through both words. The complicated
; expressions are chosen so there is no chance of overflow
; until the last step. (The term 4x^2/2^16 could be larger than 2^15
; but becomes a regular signed integer when (2^15 - 1) is
; subtracted. The canceling correction in the second bracketed
; expression ensures that it, too, will be a signed integer.)
;
only segment
assume cs:only, ds:data
picpar struc ; parameter vector in calling program
xi dw ? ; initial x coord DESTROYED BY JULINE
yi dw ? ; y coord for line
delx dw ? ; change in x for one pixel
a dw ? ; function parameter -- real part (scaled)
b dw ? ; imag part (scaled)
maxit dw ? ; maximum function iterations for a pixel
c1 dw ? ;if iterations LEFT < c1 use color 1
c2 dw ? ;if iterations LEFT < c2 use color 2 (<c1)
nbyte dw ? ; DESTROYED BY JULINE number of bytes to output
picpar ends
bigint equ 7FFFH ; 2^15 - 1
juline proc far ; param are offsets of output and struct picpar
; REGISTER USAGE FOR MAIN LOOP SCREEN CALC
; ax arith partial screen byte
; bx y param offset then output offset
; cx count of iterations
; dx high mult
; bp x point to param pointer
; si a - bigint
; di b
jul: push bp ; must be saved
mov bp,sp
add bp,6 ; points to offset of picpar,
; bp + 2 points to output offset
mov bx,[bp] ;offset of picpar
mov si, [bx].a ; keep a in si for whole routine
sub si,bigint ; shifted by bigint
mov di, [bx].b ; keep b for whole routine
mov ax, [bx].delx ;set xi
sub [bx].xi, ax ; back as initialization
byteout: ; loop for output byte
; init for pixel loop
mov cx, 3
push cx ;count of shifts to do
xor cx, cx
push cx
pixel: ; first initialize for iteration
push bp ; about to be destroyed for iteration
mov cx, [bx].maxit ; number of iterations
mov bp, [bx].delx
add bp, [bx].xi ;increment starting x
mov [bx].xi, bp ;save new one
mov bx, [bx].yi ; starting y
iterate: ; iterate the quadratic function
mov ax, bp
imul ax ; square ax -- high word to dx
rcl ax, 1 ; start first of two left shifts
rcl dx, 1
rcl ax, 1 ; low bits in ax do not matter
rcl dx, 1
sub dx, bigint ;overflow prevention
xchg dx, bp ;save first term of new x and get old x
mov ax, bx ; prepare to mult by y
imul dx ; mult dx and ax (x and y)
sub dx, di ; subtract imaginary part of parameter
cmp dx, 0FFFH ; see if following three shifts
jg enditer ; will cause positive overflow,
cmp dx, 0F000H ; or
jl enditer ;negative overflow
; otherwise can shift
rcl ax, 1 ; start first of three shifts
rcl dx, 1
rcl ax, 1
rcl dx, 1
rcl ax, 1
rcl dx, 1 ; have new y
mov ax, bx ; get old y
mov bx, dx ; and replace by new one
imul ax ; square old y -- starting on 2nd term of new x
add dx, si ; include real part of parameter
sub bp, dx ; now have new x
jo enditer
loop iterate
enditer:
pop bp
pop ax ; screen word
mov bx, [bp]
cmp cx, [bx].c1
jg havecolor ; backround color
inc ax
cmp cx, [bx].c2
jg havecolor ; color 1
inc ax
cmp cx, 0
jg havecolor ; color 2
inc ax ; color 3
havecolor:
pop cx ; shift count, replace iter count
jcxz bytedone
dec cx
push cx
sal ax, 1 ; ready for two new bits
sal ax, 1
push ax ; save intermediate screen word
jmp pixel
bytedone:
mov bx,[bp] + 2 ; get output address
mov [bx], al ; save screen byte
inc bx ; advance
mov [bp] +2, bx ; output address
mov bx, [bp] ; replace picpar offset
dec [bx].nbyte ; update number of words to generate
jz cleanup
jmp byteout
cleanup:
pop bp ; restore original base
ret 4
juline endp
; The driver for juline needs to set up the parameter struct and
; provide space for the output
data segment
param picpar <0a000h, 1 shl 14, 3 shl 10, 0 shl 14, 0 shl 12,7,5,3,4>
scrstr db 1160 dup(?)
data ends
;picpar struc ; parameter vector in calling program
; xi dw -3 shl 13 ; initial x coord DESTROYED BY JULINE
; yi dw 0 shl 15 ; y coord for line
; delx dw 3 shl 9 ; change in x for one pixel
; a dw 0 shl 14 ; function parameter -- real part (scaled)
; b dw 0 shl 12 ; imag part (scaled)
; maxit dw 7 ; maximum function iterations for a pixel
; c1 dw 5 ;if iterations LEFT < c1 use color 1
; c2 dw 3 ;if iterations LEFT < c2 use color 2 (<c1)
; nbyte dw 4 ; DESTROYED BY JULINE number of bytes to output
;picpar ends
driver: ; PUSH PARAMETER ADDRESSES
mov ax, seg data
mov ds, ax
mov ax, offset scrstr
push ax
mov ax, offset param
push ax
call far ptr jul
only ends
stack segment stack
assume ss:stack
dw 64 dup (?)
stack ends
public cleanup, driver, enditer, havecolor, iterate, jul
public juline, param, pixel, scrstr, bytedone, byteout
end driver